using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using QFramework;

// 1.请在菜单 编辑器扩展/Namespace Settings 里设置命名空间
// 2.命名空间更改后，生成代码之后，需要把逻辑代码文件（非 Designer）的命名空间手动更改
namespace QFramework.Example
{
	public partial class UIShop : ViewController
	{
		/// <summary>
		/// 默认的金币数据，正式版本应记录在Model层，这里只是做测试
		/// </summary>
		public static BindableProperty<int> Coin = new BindableProperty<int>(100);
		
		private ShopConfig _mShopConfig;
		
		public enum Modes
		{
			Buy,
			Sell
		}

		/// <summary>
		/// 默认是Buy的模式
		/// </summary>
		public Modes Mode = Modes.Buy;
		

		private void Awake()
		{
			_mShopConfig = GetComponent<ShopConfig>();
			Coin.Value=PlayerPrefs.GetInt(nameof(Coin),Coin.Value);
			Coin.Register((coin) =>
			{
				PlayerPrefs.SetInt(nameof(Coin), coin);
			}).UnRegisterWhenGameObjectDestroyed(gameObject);
		}

		/// <summary>
		/// 在界面上显示金币数量，方便测试
		/// </summary>
		private void OnGUI()
		{
			IMGUIHelper.SetDesignResolution(480,270);
			GUILayout.Label("Coin:"+Coin.Value);
		}

		private IEnumerable<ShopConfig.ShopBuyItem> mBuyItems;
		public void Show(IEnumerable<ShopConfig.ShopBuyItem> buyItems)
		{
			Mode = Modes.Buy;
			mBuyItems = buyItems;
			Content.DestroyChildren();
			foreach (var shopBuyItem in buyItems)
			{
				//var price = shopBuyItem.Price;
				var item = shopBuyItem.Item;
				var shopItem = UIShopItem
					.InstantiateWithParent(Content)
					.InitWithData(shopBuyItem.Item)
					.Show();

				
				var buyItem = shopBuyItem;
				Coin.RegisterWithInitValue(coin =>
				{
					// 当PriceGetter不为空，则更新价格
					if (buyItem.PriceGetter != null)
					{
						buyItem.Price=buyItem.PriceGetter();
					}

					shopItem.UpdateBuyPriceText(Coin.Value,buyItem.Price);
				}).UnRegisterWhenGameObjectDestroyed(shopItem.gameObject);//把事件注册到shopItem上
        
				// 上面已经设置了按钮点击事件是否监听，所以这里不需要再设置
				shopItem.BtnBuy.onClick.AddListener(() =>
				{
					//Debug.Log("点击购买");
					Coin.Value -= buyItem.Price;
					ItemKit.GetSlotGroupByKey("物品栏").AddItem(buyItem.Item);
            	
					// 当PriceGetter不为空，则更新价格
					if (buyItem.PriceGetter != null)
					{
						buyItem.Price=buyItem.PriceGetter();
		            
						shopItem.UpdateBuyPriceText(Coin.Value,buyItem.Price);
					}
				});
			}

			this.Show();
		}

		/// <summary>
		/// 对应物品的价格加成表，实际做的时候应该不需要，每个物品的价格都是固定的，在配置表中配置即可
		/// </summary>
		private Dictionary<IItem,Func<int>> mPriceTable;
		
		/// <summary>
		/// 显示出售界面物品
		/// </summary>
		/// <param name="priceTable"></param>
		public void ShowSellItems(Dictionary<IItem,ShopConfig.ShopSellItem> priceTable)
		{
			// 创建出售物品列表
			var sellItems = new List<ShopConfig.ShopSellItem>();
			
			// 遍历物品栏里所有的物品，如果数量大于0则显示在商店
			// 后期实际做的时候应该是有规定的一批可出售道具，如果背包有则可以出售，没有则显示无法出售或者置灰
			foreach (var item in ItemKit.GetSlotGroupByKey("物品栏").Slots
				         //下面的where是针对slot去重，因为可能物品栏里多个格子都有同一个道具，所以要去重，不然商店会显示多个同样的道具
				         // ToHashSet()是去重操作
				         .Where(s=>s.Count>0).Select(s=>s.Item).ToHashSet())
			{
				if (mPriceTable.ContainsKey(item))
				{
					sellItems.Add(new ShopConfig.ShopSellItem()
					{
						Item = item as Item,
						Price = mPriceTable[item](),//根据Item获取到mpriceTable里的Func<int>价格
					});
				}
			}
			
			// 设置当前商店模式为“出售”模式
			Mode = Modes.Sell;
			// 删除content下的所有子节点，再进行创建
			Content.DestroyChildren();
			foreach (var shopSellItemKV in priceTable)
			{
				var shopSellItem = shopSellItemKV.Value;
				var price = shopSellItem.Price;
				var item = shopSellItem.Item;
				var shopItem = UIShopItem.InstantiateWithParent(Content);
				shopItem.Icon.sprite = item.GetIcon;
				shopItem.Description.text = item.GetDescription;
				
				shopItem.BtnBuyText.text = $"出售({price})";
				
				// 上面已经设置了按钮点击事件是否监听，所以这里不需要再设置
				shopItem.BtnBuy.onClick.AddListener(() =>
				{
					Coin.Value += price;
					ItemKit.GetSlotGroupByKey("物品栏").SubItem(item);
					// 当点击出售后，要刷新商店出售道具显示
					// RefreshSellItems();
				});
				
				shopItem.Show();
			}
		}

		void Start()
		{

			BtnBuy.onClick.AddListener(() =>
			{
				Show(mBuyItems);
			});
			
			BtnSell.onClick.AddListener(() =>
			{
				// RefreshSellItems();
			});
			
			ItemKit.GetSlotGroupByKey("物品栏").Changed.Register(() =>
			{
				TODO://判断当前界面是出售还是购买，再刷新对应界面
				// 这里先统一刷新出售界面了，但实际上要根据当前的界面来刷新对应界面，这个后面再做
				if (Mode == Modes.Sell)
				{
					// RefreshSellItems();
				}
			}).UnRegisterWhenGameObjectDestroyed(gameObject);
		}
		
		// void RefreshSellItems()
		// {
		//
		// 	Show(mPriceTable);
		// }

		/// <summary>
		/// 显示可以购买的道具
		/// </summary>
		// void ShowBuyItems()
		// {
		// 	//Content.DestroyChildren();
		// 	
		// 	var buyItems = new List<ShopComponent.ShopBuyItem>()
		// 	{
		// 		new ShopComponent.ShopBuyItem(){Item = Items.item_iron as Item,Price = 5},
		// 		new ShopComponent.ShopBuyItem(){Item = Items.item_greensword as Item,Price = 4},
		// 		new ShopComponent.ShopBuyItem(){Item = Items.item_wood as Item,Price = 3},
		// 		new ShopComponent.ShopBuyItem(){Item = Items.item_paper as Item,Price = 2},
		// 	};
		//
		// 	Show(buyItems);
		//
		//
		// }
		
		/// <summary>
		/// 设置道具价格加成属性
		/// </summary>
		/// <param name="priceTable"></param>
		public void SetSellPriceTable(Dictionary<IItem,Func<int>> priceTable)
		{
			mPriceTable = priceTable;
		}
	}
}
